package com.wk.springboot.util;

import com.wk.springboot.adapter.ISearchHitAdapter;
import com.wk.springboot.bean.ExportEntity;
import com.wk.springboot.contants.Consts;
import com.wk.springboot.contants.ESConst;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Classname EsExportUtils
 * @Description es的导出工具
 * @Date 2020/5/30 10:32
 * @Author by weikai
 */
public final class EsExportUtils {

  private static final Logger LOG = LoggerFactory.getLogger(EsExportUtils.class);

  private EsExportUtils(){}

  //获取查询JSON的索引名称、类型名称和查询体
  public static String[] parseQueryJSON(String queryJSON, String index, String type) throws Exception {
    //从queryJSON中获取该查询的索引名称、类型名称 和 查询体
//    String[] queryParams = parseQueryJSONUtil(queryJSON);

    //如果查询JSON中指明了索引和类型名称，则该查询使用该索引和类型名称,否则使用DataSource中指定的索引和类型名称
//    if (StringUtils.isEmpty(queryParams[0])) {
//      queryParams[0] = index;
//      queryParams[1] = type;
//      LOG.warn("查询JSON中未指明索引和类型名称，该查询使用DataSource中指定的索引{}和类型名称{}，查询JSON如下：{}", index, type, queryJSON);
//    }
//    if (StringUtils.isBlank(queryParams[2])) {
//      throw new Exception("查询JSON格式不正确，请检查，查询JSON如下：" + queryJSON);
//    }
    return new String[]{};
  }

  /**
   * 根据fieldName 从hit 中获取 fieldValue, fieldName的形式可以是组合 (带"||")
   */
  public static String getFieldValueAssembly(String fieldName, ISearchHitAdapter hit) {
    /* 根据 fieldName 获取fieldValue; 同时使得ES能类似结构化SQL一样补充常量, 拼接多个列  */
    return Arrays.stream(fieldName.split("\\|\\|"))
        .map(subFieldName -> getFieldValue(subFieldName, hit))
        .collect(Collectors.joining());
  }

  /**
   * 根据fieldName 从hit 中获取 fieldValue
   */
  private static String getFieldValue(String fieldName, ISearchHitAdapter hit) {
    String fieldValue = "";
    fieldName = StringUtils.trim(fieldName);
            /* 分三种情况取fieldValue,
               1. fieldName 是 index 内置的字段定义
               2. fieldName 加了单引号或者双引号, 则去掉引号作为常量
               3. 正常情况, fieldName 是来自query的 source include 或 field 枚举 */
    if (Consts.isBuiltInFieldName(fieldName)) {
      switch (fieldName) {
        case ESConst.ES_ID:
          fieldValue = hit.getId();
          break;
        case ESConst.ES_SCORE:
          fieldValue = hit.getScoreStr();
          break;
        case ESConst.ES_SOURCE:
          fieldValue = hit.getSourceAsString();
          break;
        case ESConst.ES_INDEX:
          fieldValue = hit.getIndex();
          break;
        case ESConst.ES_TYPE:
          fieldValue = hit.getType();
          break;
        default:
      }
    } else if (StringUtils.startsWith(fieldName, "'")) {
      /* 若fieldName以单引号开头, 则表明是常量; 详见 ResultDefine 定义的示例 */
      fieldValue = StringUtils.strip(fieldName, "'");
    } else if (StringUtils.startsWith(fieldName, "\"")) {
      /* 若fieldName以双引号开头, 同上 */
      fieldValue = StringUtils.strip(fieldName, "\"");
    } else {
      fieldValue = hit.getFieldValue(fieldName);
    }
    return fieldValue;
  }

  // 将查询出来的单个JOSN文档转换成一个文本行
  public static List<String> extractNestedLineData(String[] fieldNames, ISearchHitAdapter adapterHit, Map<String, ExportEntity.field> fields, boolean isTrans) {

    ArrayList<String> nestedLineData = new ArrayList();

    Map<String, Object> valueMap = new HashMap();

    //将es返回的JSON map结果转换为嵌套的Map结构，调整组装map中的key的命名，使map中key的命名与查询JSON中的字段名称一致
//    parseNestedValue(adapterHit.getSource(), valueMap, "");

    //将一个JSON文档转换成的嵌套结构的Map--rowValue,转换成多个可用来存储于结构化数据库中的扁平Map对象--List<Map<String,Object>>
//    List<Map<String, Object>> rowValueList = changeNestedMap2List(valueMap);

    //将每个扁平的Map对象转换成可用于导入数据库的字符串
/*    for (Map<String, Object> rowMap : rowValueList) {
      StringBuilder lineData = new StringBuilder();
      // 遍历每个字段
      for (String fieldName : fieldNames) {
        // 先判断其是否存在于主表字段中
        Object fieldValue = rowMap.get(fieldName);

        *//* 若不存在主表中 *//*
        if (fieldValue == null) {
          fieldValue = getFieldValueAssembly(fieldName, adapterHit);
        }

        //针对特殊字段进行字段值转换
        fieldValue = trans(fieldName, fieldValue, fields, isTrans);

        // 如果字段值还为空，则默认为空字符串
        if (fieldValue == null) {
          fieldValue = "";
        }
        // 拼接字段信息
        //com.thunisoft.solutionutil.lang.StringUtils.replaceSpecStrForDB(fieldValue.toString())
        lineData.append(com.thunisoft.solutionutil.lang.SolutionStringUtils.replaceSpecStrForDB(fieldValue.toString()));
        lineData.append(Consts.COLUMN_SPLIT);
      }
      lineData.replace(lineData.length() - 1, lineData.length(), " ");
      nestedLineData.add(lineData.toString().trim() + "\r\n");
    }*/

    return nestedLineData;
  }

}
